/*
 * SMPP Encoder/Decoder
 * Copyright (C) 2006 redtaza@users.sourceforge.net
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

/// @file aux_types.cpp
/// @brief Functions declarations from aux_types.h

#include "aux_types.h"

/// @brief Prints a hex dump of a buffer.
/// @note The debug are rows of 16 octets with their hexadecimal value on
/// the left and if printable their character representation on the right
/// or a dot (.) if not printable.
/// @param buff The buffer to print.
/// @param len Number of octets in buff.
/// @param file The C file stream to write to (default standard output).
void Smpp::chex_dump(const Smpp::Uint8* buff, Smpp::Uint32 len, FILE* file)
{
    if(len == 0)
        return;

    Smpp::Uint32 i;
    for(i = 0; i < len; ++i) {
        if(i != 0 && i % 16 == 0) {
            fprintf(file, "   ");
            for(Smpp::Uint32 j = i - 16; j < i; ++j)
                if(buff[j] > 31 && buff[j] < 128)
                    fprintf(file, "%c", static_cast<char>(buff[j]));
                else
                    fprintf(file, ".");
            fprintf(file, "\n");
        }
    
        fprintf(file, "%02x ", buff[i]);
    }

    Smpp::Uint32 m = i % 16 ? 16 - i % 16 : 0; // octets needed to make up 16
    m && fprintf(file, "%*c", m * 3, ' ');
    fprintf(file, "   ");
    for(Smpp::Uint32 j = i % 16 ? i - i % 16 : i - 16 ; j < i; ++j)
        if(buff[j] > 31 && buff[j] < 128)
            fprintf(file, "%c", static_cast<char>(buff[j]));
        else
            fprintf(file, ".");

    fprintf(file, "\n");
    fflush(file);
}

/// @brief Prints a hex dump of a buffer.
/// @note The debug are rows of 16 octets with their hexadecimal value on
/// the left and if printable their character representation on the right
/// or a dot (.) if not printable.
/// @param buff The buffer to print.
/// @param len Number of octets in buff.
/// @param file The C++ file stream to write to (default standard output).
void Smpp::hex_dump(const Smpp::Uint8* buff, Smpp::Uint32 len, std::ostream& os)
{
    if(len == 0)
        return;

    Smpp::Uint32 i;
    for(i = 0; i < len; ++i) {
        if(i != 0 && i % 16 == 0) {
            os << "   ";
            for(Smpp::Uint32 j = i - 16; j < i; ++j)
                if(buff[j] > 31 && buff[j] < 128)
                    os << static_cast<char>(buff[j]);
                else
                    os << ".";
            os << "\n";
        }
    
        os << std::setw(2) << std::setfill('0')
           << std::hex << (int)buff[i] << std::dec << ' ';
    }

    Smpp::Uint32 m = i % 16 ? 16 - i % 16 : 0;// octets needed to make up 16
    m && os << std::setw(m*3) << std::setfill(' ') << ' ';
    
    os << "   ";
    for(Smpp::Uint32 j = i % 16 ? i - i % 16 : i - 16 ; j < i; ++j)
        if(buff[j] > 31 && buff[j] < 128)
            os << static_cast<char>(buff[j]);
        else
            os << ".";

    os << "\n";
    std::flush(os);
}

